package cn.iocoder.yudao.module.asasc.dal.mysql.campaign;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.asasc.controller.admin.campaign.vo.CampaignDataPageReqVO;
import cn.iocoder.yudao.module.asasc.dal.dataobject.campaign.CampaignDataDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 广告数据 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface CampaignDataMapper extends BaseMapperX<CampaignDataDO> {

    default PageResult<CampaignDataDO> selectPage(CampaignDataPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<CampaignDataDO>()
                .betweenIfPresent(CampaignDataDO::getDate, reqVO.getDate())
                .eqIfPresent(CampaignDataDO::getCountryOrRegion, reqVO.getCountryOrRegion())
                .eqIfPresent(CampaignDataDO::getCampaignId, reqVO.getCampaignId())
                .likeIfPresent(CampaignDataDO::getCampaignName, reqVO.getCampaignName())
                .eqIfPresent(CampaignDataDO::getIsDeleted, reqVO.getIsDeleted())
                .eqIfPresent(CampaignDataDO::getCampaignStatus, reqVO.getCampaignStatus())
                .likeIfPresent(CampaignDataDO::getAppName, reqVO.getAppName())
                .eqIfPresent(CampaignDataDO::getAdamId, reqVO.getAdamId())
                .eqIfPresent(CampaignDataDO::getServingStatus, reqVO.getServingStatus())
                .eqIfPresent(CampaignDataDO::getCountriesOrRegions, reqVO.getCountriesOrRegions())
                .eqIfPresent(CampaignDataDO::getDisplayStatus, reqVO.getDisplayStatus())
                .eqIfPresent(CampaignDataDO::getSupplySources, reqVO.getSupplySources())
                .eqIfPresent(CampaignDataDO::getAdChannelType, reqVO.getAdChannelType())
                .eqIfPresent(CampaignDataDO::getOrgId, reqVO.getOrgId())
                .betweenIfPresent(CampaignDataDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(CampaignDataDO::getDate));
    }

    default PageResult<CampaignDataDO> selectPageByKey(CampaignDataPageReqVO reqVO) {
        List<String> countriesList = reqVO.getCountries() != null ?
                Stream.of(reqVO.getCountries()).collect(Collectors.toList()) : null;
        List<Long> adamIds = reqVO.getAdamIds() != null ?
                Stream.of(reqVO.getAdamIds()).collect(Collectors.toList()) : null;

        QueryWrapper<CampaignDataDO> queryWrapper = new QueryWrapper<CampaignDataDO>()
                .eq(reqVO.getOrgId() != null, "org_id", reqVO.getOrgId())
                .in(countriesList != null, "country_or_region", countriesList)
                .in(adamIds != null, "adam_id", adamIds)
                .between("date", reqVO.getDate()[0], reqVO.getDate()[1]);

        // 动态设置 select 字段
        List<String> selectFields = new ArrayList<>();
        List<String> orderByFields = new ArrayList<>();

        // 根据 dimension 字段进行分组
        if (reqVO.getDimension() != null) {
            for (int i = 0; i < reqVO.getDimension().length; i++) {
                String dim = reqVO.getDimension()[i];
                switch (dim) {
                    case "country_or_region":
                    case "adam_id":
                    case "campaign_name":
                    case "date":
                        queryWrapper.groupBy(dim);
                        selectFields.add(dim);
                        if (i < reqVO.getDimension().length - 1) {
                            orderByFields.add(dim + " desc");
                        } else {
                            orderByFields.add(dim);
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("Unknown dimension: " + dim);
                }
            }
        }

        selectFields.add("SUM(local_spend_amount) AS localSpendAmount");
        selectFields.add("SUM(impressions) AS impressions");
        selectFields.add("SUM(taps) AS taps");
        selectFields.add("SUM(installs) AS installs");
        selectFields.add("SUM(new_downloads) AS newDownloads");
        selectFields.add("SUM(re_downloads) AS reDownloads");
        selectFields.add("AVG(ttr) AS ttr");
        selectFields.add("AVG(conversion_rate) AS conversionRate");
        selectFields.add("AVG(avg_cpa_amount) AS avgCpaAmount");
        selectFields.add("AVG(avg_cpt_amount) AS avgCptAmount");
        selectFields.add("AVG(avg_cpm_amount) AS avgCpmAmount");
        selectFields.add("AVG(daily_budget_amount) AS dailyBudgetAmount");
        selectFields.add("SUM(asc_sales) AS ascSales");
        selectFields.add("SUM(asc_proceeds) AS ascProceeds");
        selectFields.add("SUM(asc_impressions) AS ascImpressions");
        selectFields.add("SUM(asc_taps) AS ascTaps");
        selectFields.add("SUM(asc_installs) AS ascInstalls");
        selectFields.add("SUM(asc_re_installs) AS ascReInstalls");
        selectFields.add("SUM(asc_upt_installs) AS ascUptInstalls");
        selectFields.add("AVG(asc_ttr) AS ascTtr");
        selectFields.add("AVG(asc_conversion_rate) AS ascConversionRate");
        selectFields.add("SUM(asc_trial) AS ascTrial");
        selectFields.add("SUM(asc_renewal) AS ascRenewal");
        selectFields.add("SUM(asc_refund) AS ascRefund");
        selectFields.add("SUM(asc_refund_sales) AS ascRefundSales");
        selectFields.add("SUM(asc_refund_proceeds) AS ascRefundProceeds");
        selectFields.add("SUM(naturally_installs) AS naturallyInstalls");
        selectFields.add("SUM(profit) AS profit");

        // 使用 join 将 selectFields 转换为一个字符串，并传递给 select
        queryWrapper.select(String.join(", ", selectFields));
        //排序
        queryWrapper.orderBy(true, false, String.join(", ", orderByFields));

        return selectPage(reqVO, queryWrapper);
    }

    int updateCampaignDataByKey(CampaignDataDO updateObj);

    default List<CampaignDataDO> selectListByKey(Long adamId, LocalDate date, String country) {
        return selectList(new LambdaQueryWrapperX<CampaignDataDO>()
                .eq(CampaignDataDO::getAdamId, adamId)
                .eq(CampaignDataDO::getDate, date)
                .eq(CampaignDataDO::getCountryOrRegion, country));
    }
}